package com.daiqee.service.impl;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.daiqee.pojo.GoodsList;
import com.daiqee.pojo.StockOut;
import com.daiqee.dao.mapper.StockOutMapper;

/**
 * 出库
 * 
 * <br/>
 * @since JDK 1.8
 * @version  V2.1
 * @author RichardTang 
 * @date: 2018年5月8日 上午8:27:30
 * @package com.daiqee.service.impl
 * @copyright:Copyright (c) 2018, 1245811923@qq.com All Rights Reserved.
 */
@Service
public class StockOutService extends ServiceImpl<StockOutMapper, StockOut> {

	@Autowired
	private StockOutMapper stockOutMapper;
	
	@Autowired
	private GoodsListService goodsListService;

	/**
	 * 删除出库单
	 * 
	 * @param idList
	 * 			 需要删除的id号
	 * 
	 * @param goods
	 * 			 更新的参数
	 * 
	 * @return true:成功 false:失败
	 */
	public Boolean removeStockOutOrder(List<String> ids){
		
		stockOutMapper.delete(new EntityWrapper<StockOut>().in("stock_out_order_number", ids));
		
		//通过订单的id查询出被拆分出来的货物
		List<GoodsList> readyOutRepositoryGoods = goodsListService.selectList(
		    new EntityWrapper<GoodsList>().in("goods_list_out_stock_order_number", ids));
		
		//取出这些货物上的原来所属的货物的id
		ArrayList<Integer> metaMasterIds = new ArrayList<Integer>();
		for(GoodsList outGoods : readyOutRepositoryGoods) {
			metaMasterIds.add(outGoods.getGoodsListOutStockBackId());
			//将这些货物设置成正常货物状态
			outGoods.setGoodsListOutFlag("N");
			outGoods.setGoodsListOutStockOrderNumber("0");
		}
		//根据需要被合并的货物存放的一个属性取出来的值来查询是否还存在原先的数据
		List<GoodsList> metaGoods = goodsListService.selectBatchIds(metaMasterIds);
		//判断查询出来的元数据的集合是否为空,如果为空,则代表没有元数据,直接添加即可,无需对数据进行合并
		if(metaGoods != null && !(metaGoods.isEmpty())) {
			//这个是需要合并的
			List<GoodsList> updateList = new ArrayList<GoodsList>();
			//这个是直接添加的
			List<GoodsList> insertList = new ArrayList<GoodsList>();
			
			//将查询到的元数据集合转成Map集合,货物的id为key
			HashMap<Integer,GoodsList> metaMap = new HashMap<Integer,GoodsList>();
			for(GoodsList itemMetaGoods : metaGoods) {
				metaMap.put(itemMetaGoods.getGoodsListProductId(), itemMetaGoods);
			}
			//遍历需要合并值的集合,并通过他的元数据字段列的值从查询到的元数据Map集合中取值
			for(GoodsList itemMargeGoods : readyOutRepositoryGoods) {
				//通过需要合并的货物的backId从map集合中取值
				GoodsList metaMapOfGoods = metaMap.get(itemMargeGoods.getGoodsListOutStockBackId());
				//如果取到的值不为Null着代表这个需要合并的货物有同类的数据,进行数据的合并
				if(metaMapOfGoods != null) {
					//合并库存量
					metaMapOfGoods.setGoodsListProductAmount(
					    metaMapOfGoods.getGoodsListProductAmount() + itemMargeGoods.getGoodsListProductAmount());
					updateList.add(metaMapOfGoods);
				}else {
					itemMargeGoods.setGoodsListOutStockBackId(-1);
					//没有取到值,就直接添加
					insertList.add(itemMargeGoods);
				}
			}
			if(updateList != null && !updateList.isEmpty()) {
				System.out.println(updateList);
				goodsListService.updateBatchById(updateList);
			}
			if(insertList != null && !insertList.isEmpty()) {
				goodsListService.insertBatch(insertList);
			}
		}else {
			//如果为空,就代表已经不存在原来的数据了,直接添加进去即可
			goodsListService.insertBatch(readyOutRepositoryGoods);
		}
		return true;
	}
	/**
	 * 更新出库单
	 * 
	 * @param decreaseGoodsList 
	 * 				货物比原来出库少			
	 * @param increaseGoodsList
	 * 				货物比原来出库多
	 * @param backRepository
	 * 				不打算出库的货物
	 * @return boolean
	 * 
	 */
	public Boolean updateGoodsListAndStockOut(ArrayList<GoodsList> decreaseGoodsList,ArrayList<GoodsList> increaseGoodsList,
			ArrayList<GoodsList> backRepository,StockOut stockOutOrder){
		
		//更新出库单信息
		stockOutMapper.updateById(stockOutOrder);
		
		if(backRepository != null && !(backRepository.isEmpty())) {
			
			//是拆分货物
			ArrayList<GoodsList> isBackGoods = new ArrayList<GoodsList>();
			
			//存储拆分货物的id,只要id
			ArrayList<Integer> deleteGoodsId = new ArrayList<Integer>();
			
			//非拆分货物
			ArrayList<GoodsList> notBackGoods = new ArrayList<GoodsList>();
			
			//存储拆分货物所属的backId,这里必须使用set避免重复的backId
			HashSet<Integer> backIds = new HashSet<Integer>();
			
			//进行区分和数据包装
			for(GoodsList item : backRepository) {
				
				if(item.getGoodsListOutStockBackId() <= 0) {
					/*非拆分货物*/

					//设置出库量 = 0;
					item.setGoodsListOutStockCount(0);
					
					//设置是否出库标识为 N
					item.setGoodsListOutFlag("N");
					
					//添加到飞拆分货物集合中
					notBackGoods.add(item);
				}else {
					/*拆分货物*/
					isBackGoods.add(item);
					
					deleteGoodsId.add(item.getGoodsListProductId());
					
					backIds.add(item.getGoodsListOutStockBackId());
				}
				
			}
			
			if(backIds != null && !(backIds.isEmpty())) {
				
				//更具backId集合来查询所属的元数据货物
				List<GoodsList> backIdGoodsList = goodsListService.selectBatchIds(backIds);
				
				//包装成一个Map ProductId:backIdGoodsList方便操作
				HashMap<Integer,GoodsList> PidGoodsMap = new HashMap<Integer,GoodsList>();
				
				for(GoodsList itemGoods : backIdGoodsList) {
					
					PidGoodsMap.put(itemGoods.getGoodsListProductId(), itemGoods);
				}
				
				//转成map后,清空之前的数据,用来存储聚合好值后的数据 backIdGoodsList
				backIdGoodsList.clear();
				
				//进行值的整合
				for(GoodsList isBackGoodsItem: isBackGoods) {
					
					GoodsList metaGoods = PidGoodsMap.get(isBackGoodsItem.getGoodsListOutStockBackId());
					
					metaGoods.setGoodsListProductAmount(metaGoods.getGoodsListProductAmount() + isBackGoodsItem.getTempOutStockCount());
					
					//出库数设置为全部出库
					metaGoods.setGoodsListOutStockCount(metaGoods.getGoodsListProductAmount());
					
					backIdGoodsList.add(metaGoods);
				
			    }
			
				/*数据库更新*/
				if(!(isBackGoods.isEmpty()) && isBackGoods.size() > 0) {
					
					//删除拆分区数据
					goodsListService.deleteBatchIds(deleteGoodsId);
				}
				
				if(!(backIdGoodsList.isEmpty()) && backIdGoodsList.size() > 0) {
					
					//更新聚合好值后的原数据
					goodsListService.updateBatchById(backIdGoodsList);
				}
				
			}
			
			/*数据库更新*/
			if(!(notBackGoods.isEmpty()) && notBackGoods.size() > 0) {
				
				//更新非拆分数据
				goodsListService.updateBatchById(notBackGoods);
			}
			
		}
		
		
		//判断是否有减货物的
		if(decreaseGoodsList != null && !(decreaseGoodsList.isEmpty())) {
			
			//查询原数据,就是backId对应的货物
			HashSet<GoodsList> queryMetaGoodsList = new HashSet<GoodsList>();
			
			//存储非原数据
			ArrayList<GoodsList> saveNotMetaGoodsList = new ArrayList<GoodsList>();
			
			//存储原数据
			ArrayList<GoodsList> saveMetaGoodsList = new ArrayList<GoodsList>();
			
			//存储非元数据的backId
			HashSet<Integer> saveNotMetaBackIds = new HashSet<Integer>();
			
			for(GoodsList goods : decreaseGoodsList) {
				
				if(goods.getGoodsListOutStockBackId() < 0) {
					
					saveMetaGoodsList.add(goods);
				}else {
					
					//存储非元数据的backId数据到 一个集合中
					saveNotMetaBackIds.add(goods.getGoodsListOutStockBackId());
					
					//非元数据 -> 更新自己 -> 更新对应的元数据
					saveNotMetaGoodsList.add(goods);
				}
				
			}
			
			//非元数据集合
			if(!(saveNotMetaBackIds.isEmpty())) {
				//查询非元数据的 元数据货物queryMetaGoodsList = 
				List<GoodsList> tempMetaGoodsList = goodsListService.selectBatchIds(saveNotMetaBackIds);
				
				for(GoodsList item : tempMetaGoodsList) {
					
					queryMetaGoodsList.add(item);
				}
				
				//包装过后的元数据集合
				HashMap<Integer,GoodsList> queryMetaGoodsMap = new HashMap<Integer,GoodsList>();
				
				//包装成map 方便操作
				for(GoodsList goods : queryMetaGoodsList) {
					queryMetaGoodsMap.put(goods.getGoodsListProductId(), goods);
				}
				
				//聚合值
				queryMetaGoodsList.clear();
				
				//非元数据
				for(GoodsList goodsItem : saveNotMetaGoodsList) {
					
					GoodsList currentGoodsMeta = queryMetaGoodsMap.get(goodsItem.getGoodsListOutStockBackId());
					
					currentGoodsMeta.setGoodsListProductAmount( currentGoodsMeta.getGoodsListProductAmount() + (goodsItem.getTempOutStockCount() - goodsItem.getGoodsListOutStockCount()));
					
					currentGoodsMeta.setGoodsListOutStockCount(currentGoodsMeta.getGoodsListProductAmount());
					
					queryMetaGoodsList.add(currentGoodsMeta);
				}
			}
			
			if(!(saveMetaGoodsList.isEmpty())) {
				//元数据
				
				//存储从本身就是元数据的数据中拆分出来的数据
				ArrayList<GoodsList> splitGoodsData = new ArrayList<GoodsList>();
				
				//本身就是元数据
				for(GoodsList goodsItem : saveMetaGoodsList) {
					
					//切割出来的部分
					GoodsList splitGoods = goodsItem.clone();
					
					//计算差值
					int differenceValue = goodsItem.getTempOutStockCount() - goodsItem.getGoodsListOutStockCount();
					
					goodsItem.setGoodsListOutStockBackId(-1);
					
					goodsItem.setGoodsListOutFlag("N");
					
					goodsItem.setGoodsListProductAmount(differenceValue);
					
					goodsItem.setGoodsListOutStockCount(differenceValue);

					goodsItem.setGoodsListOutStockOrderNumber("0");
					
					splitGoods.setGoodsListProductId(null);
					
					splitGoods.setGoodsListOutStockBackId(goodsItem.getGoodsListProductId());
					
					splitGoodsData.add(splitGoods);
				}
				
				if(splitGoodsData != null && !(splitGoodsData.isEmpty())) {
					
					goodsListService.insertBatch(splitGoodsData);
				}
				
			}
			
			//更新原数据
			if(queryMetaGoodsList != null && !(queryMetaGoodsList.isEmpty())) {
				
				goodsListService.updateBatchById(new ArrayList<GoodsList>(queryMetaGoodsList));
			}
			
			if(saveNotMetaGoodsList != null && !(saveNotMetaGoodsList.isEmpty())) {
				
				goodsListService.updateBatchById(saveNotMetaGoodsList);
			}
			
			if(saveMetaGoodsList != null && !(saveMetaGoodsList.isEmpty())) {
				
				goodsListService.updateBatchById(saveMetaGoodsList);
			}
			
		}
		
		//判断是否有增加货物的
		if(increaseGoodsList != null && !(increaseGoodsList.isEmpty())) {
			
			//存储元数据项
			
			//拿到backId,查询原数据
			HashSet<Integer> metaDataId = new HashSet<Integer>();
			
			for(GoodsList goodsItem : increaseGoodsList) {
				
				goodsItem.setGoodsListProductAmount(goodsItem.getGoodsListOutStockCount());
				
				if(goodsItem.getGoodsListOutStockBackId() > 0) {
					
					metaDataId.add(goodsItem.getGoodsListOutStockBackId());
				}
				
			}
			
			//元数据 集合
			List<GoodsList> metaDataList = goodsListService.selectBatchIds(metaDataId);
			
			//存储元数据的map
			HashMap<Integer,GoodsList> metaDataMap = new HashMap<Integer,GoodsList>();
			
			//格式化元数据
			for(GoodsList metaDataItem : metaDataList) {
				
				metaDataMap.put(metaDataItem.getGoodsListProductId(), metaDataItem);
			}
			
			metaDataList.clear();
			
			//当元数据的货物数变成0时,需要删除该货物
			ArrayList<Integer> deleteMetaIds = new ArrayList<Integer>();
			
			//聚合值
			for(GoodsList goodsItem : increaseGoodsList) {
				
				GoodsList metaDataMapItem = metaDataMap.get(goodsItem.getGoodsListOutStockBackId());
				
				metaDataMapItem.setGoodsListProductAmount( 
				    metaDataMapItem.getGoodsListProductAmount() - (goodsItem.getGoodsListOutStockCount() - goodsItem.getTempOutStockCount()));
				
				metaDataMapItem.setGoodsListOutStockCount(metaDataMapItem.getGoodsListProductAmount());
				
				if(metaDataMapItem.getGoodsListProductAmount() <= 0) {
					
					deleteMetaIds.add(metaDataMapItem.getGoodsListProductId());
					
					goodsItem.setGoodsListOutStockBackId(-1);
				}
				
				metaDataList.add(metaDataMapItem);
				
			}
			
			goodsListService.updateBatchById(increaseGoodsList);
			
			if(!(metaDataList.isEmpty()) && metaDataList.size() > 0) {
				goodsListService.updateBatchById(metaDataList);
			}
			
			if(!(deleteMetaIds.isEmpty()) && deleteMetaIds.size() > 0) {
				goodsListService.deleteBatchIds(deleteMetaIds);
			}
		}
		return true;
	}


	/**
	 * 添加出库单
	 * 
	 * @param splitResultMap
	 * 			存放了拆分后的货物信息
	 * 
	 * @param stockOut
	 * 			入库信息
	 * 
	 * @return true:成功 false:失败
	 * 
	 * @throws Exception 
	 */
	public Boolean addStockOutOrder(Map<String, List<GoodsList>> splitResultMap, StockOut stockOut) throws Exception {
		//201805311847030100 201805311912380102 
		try {
			
			//拿到出库的那批货物
			List<GoodsList> outGoodsList = splitResultMap.get("outGoods");
			
			//添加入库单号
			stockOutMapper.insert(stockOut);
			
			//设置出库货物对应的出库单
			for (GoodsList item : outGoodsList) {
				item.setDeleteFlag("N");
				//设置出库id
				item.setGoodsListOutStockOrderNumber(stockOut.getStockOutOrderNumber());
			}
			
			//判断此次货物是否全部出库,没有拆分
			if(!(splitResultMap.get("unOutGoods").isEmpty())) {
				
				//添加拆分后剩余的货物
				goodsListService.updateBatchById(splitResultMap.get("unOutGoods"));
			}
			
			//添加出库货物
			goodsListService.insertOrUpdateAllColumnBatch(outGoodsList);
			
	   }catch (Exception e) {
		   throw new Exception();
	   }
		
	   return true;
	}
}
